package cn.exrick.common.alipay;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.AlipayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wangming
 * @date 2017-04-23 15:02
 **/
@Service
public class AlipayService {

    private Logger log = LoggerFactory.getLogger(AlipayService.class);

    @Value("${ALIPAY_APP_ID}")
    public String appId;
    @Value("${ALIPAY_PARTNER}")
    public String partner;
    @Value("${ALIPAY_SELLER_ID}")
    public String sellerId;
    // 私钥
    @Value("${ALIPAY_APP_PRIVATE_KEY}")
    public String privateKey;
    // 秘钥
    @Value("${ALIPAY_PUBLIC_KEY}")
    public String publicKey;

    @Value("${ALIPAY_PAY_NOTIFY_URL}")
    public String payNotifyUrl;

    // 旧版参数 signType=RSA(SHA1WithRSA)
    /*public String sendAppPay(String outTradeNo, String body, String subject, String totalFee){
        Map<String,String> params = new HashMap<String,String>();
        params.put("service", "mobile.securitypay.pay");
        params.put("partner", partner);
        params.put("_input_charset", AlipayConfig.CHARSET);
        params.put("notify_url", notifyUrl);
        params.put("out_trade_no", outTradeNo);
        params.put("subject", subject); //商品的标题/交易标题/订单标题/订单关键字等。该参数最长为128个汉字。
        params.put("payment_type", "1");
        params.put("seller_id", sellerId);
        params.put("total_fee", totalFee);
        params.put("body", body);

        String data = AlipayCore.createLinkString(params);
        try {
            // 将待签名字符串使用私钥签名
            String RSASign = URLEncoder.encode(RSA.sign(data, privateKey, AlipayConfig.CHARSET), AlipayConfig.CHARSET);
            data += "&sign="+RSASign+"&sign_type=" + AlipayConfig.SIGN_TYPE;
            return data;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }*/

    // 新版参数 signType=RSA2(SHA256WithRSA)
    public String sendAppPay(String outTradeNo, String body, String subject, String passbackParams, BigDecimal totalAmount){
        // 业务请求参数的集合
        JSONObject bizContentJson = new JSONObject();
        bizContentJson.put("body", body);
        bizContentJson.put("subject", subject); //商品的标题/交易标题/订单标题/订单关键字等。该参数最长为128个汉字。
        bizContentJson.put("out_trade_no", outTradeNo);
        bizContentJson.put("total_amount", String.valueOf(totalAmount.setScale(2)));
        bizContentJson.put("product_code", "QUICK_MSECURITY_PAY");
        if(StringUtils.isNotBlank(passbackParams)){
            try {
                bizContentJson.put("passback_params", URLEncoder.encode(passbackParams, AlipayConstants.CHARSET_UTF8));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        SimpleDateFormat df = new SimpleDateFormat(AlipayConstants.DATE_TIME_FORMAT);
        Map<String,String> paramsMap = new HashMap<String,String>();
        paramsMap.put(AlipayConstants.APP_ID, appId);
        paramsMap.put(AlipayConstants.METHOD, "alipay.trade.app.pay");
        paramsMap.put(AlipayConstants.CHARSET, AlipayConstants.CHARSET_UTF8);
        paramsMap.put(AlipayConstants.FORMAT, AlipayConstants.FORMAT_JSON);
        paramsMap.put(AlipayConstants.SIGN_TYPE, AlipayConstants.SIGN_TYPE_RSA2);
        paramsMap.put(AlipayConstants.TIMESTAMP, df.format(new Date()));
        paramsMap.put(AlipayConstants.VERSION, "1.0");
        paramsMap.put(AlipayConstants.NOTIFY_URL, payNotifyUrl);
        paramsMap.put(AlipayConstants.BIZ_CONTENT_KEY, bizContentJson.toJSONString());

        String content = AlipaySignature.getSignContent(paramsMap);

        log.info("【支付宝支付】待签名参数：{}", content);
        try {
            String sign = AlipaySignature.rsa256Sign(content, privateKey, AlipayConstants.CHARSET_UTF8);
            paramsMap.put(AlipayConstants.NOTIFY_URL, URLEncoder.encode(payNotifyUrl, AlipayConstants.CHARSET_UTF8));
            paramsMap.put(AlipayConstants.BIZ_CONTENT_KEY, URLEncoder.encode( bizContentJson.toJSONString(), AlipayConstants.CHARSET_UTF8));
            paramsMap.put(AlipayConstants.SIGN, URLEncoder.encode(sign, AlipayConstants.CHARSET_UTF8));

            content = AlipaySignature.getSignContent(paramsMap);

            log.info("【支付宝支付】请求参数：{}", content);

            return content;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    public static void main(String[] args) throws AlipayApiException {
        String json = "{\n" +
                "\t\"gmt_create\": \"2018-11-01 17:05:03\",\n" +
                "\t\"charset\": \"UTF-8\",\n" +
                "\t\"seller_email\": \"qingjiangtech@163.com\",\n" +
                "\t\"subject\": \"商品标题\",\n" +
                "\t\"sign\": \"Yowh5E6ErE7Vg+ZoqQDYGeuTYJfPLOVgF84wGYpi91yZnUZ7QWVjGV+GrrnM7rk9KnUxxWxqTn57q7D0brkN766uyXkWE+QUQOF3npzVgfiiriTF7MJJxQLV8lZmQ2PxBNG9+h1N99tx1rABXV9x1ATWfvaPZhNhkIdi9Mj5/L9WfK6LkPDgCSa3ktSlFVpceaQDCbeaV+UToi1v6Qv67RWlxx7R7OXqyjVVSEjNHVi+Uy9ki3ItUmKeTbMbSg5vJkoitkbmco/+rUc530xrxX+0inWUScAkAlNL4Ar4xleU/uy8zdyzrdQuL1KzzgevbAILsm9DeZAMAKPvn1lRVQ==\",\n" +
                "\t\"body\": \"商品描述\",\n" +
                "\t\"buyer_id\": \"2088212092449634\",\n" +
                "\t\"invoice_amount\": \"0.10\",\n" +
                "\t\"notify_id\": \"2018110100222170503049631017707163\",\n" +
                "\t\"fund_bill_list\": \"[{\\\"amount\\\":\\\"0.10\\\",\\\"fundChannel\\\":\\\"ALIPAYACCOUNT\\\"}]\",\n" +
                "\t\"notify_type\": \"trade_status_sync\",\n" +
                "\t\"trade_status\": \"TRADE_SUCCESS\",\n" +
                "\t\"receipt_amount\": \"0.10\",\n" +
                "\t\"app_id\": \"2018102561881045\",\n" +
                "\t\"buyer_pay_amount\": \"0.10\",\n" +
                "\t\"sign_type\": \"RSA2\",\n" +
                "\t\"seller_id\": \"2088231870832703\",\n" +
                "\t\"gmt_payment\": \"2018-11-01 17:05:03\",\n" +
                "\t\"notify_time\": \"2018-11-01 17:05:03\",\n" +
                "\t\"version\": \"1.0\",\n" +
                "\t\"out_trade_no\": \"154106309282823\",\n" +
                "\t\"total_amount\": \"0.10\",\n" +
                "\t\"trade_no\": \"2018110122001449631005189674\",\n" +
                "\t\"auth_app_id\": \"2018102561881045\",\n" +
                "\t\"buyer_logon_id\": \"139****6026\",\n" +
                "\t\"point_amount\": \"0.00\"\n" +
                "}";
        JSONObject jsonObject = JSON.parseObject(json);
        System.out.println(jsonObject.get("sign"));

        Map<String, String> map = JSONObject.parseObject(json, Map.class);
        System.out.println(map.get("sign"));
        String publickKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxxMdttsLcSdbj0/PCfunRKFS9pRCGf6E5I28xURuKPzAJGK4PfsNWTGQD6/9w12jScDOkUU36g/Tzz1HlfgZLAzUvsdJWzcfgszCUaaivkbPckGD2LywHU3TXyKybz/Z5IIlnR/5lNucAbmRp7drXtEkpZSB3QFCg5NV/uCRHQlDb+w8GrtL+UV5ekYg9xvog+b1KlhUnUOR/vXqroG6eaVCpgj/vTc9POP4+9K9b+QWvd+Dm2sofKOLuOw0YELFMyfyVnLwTXvaU6PpSdk6oxgpsvVhMu1hGI2u8CIxUmLe3LYvmGuW1Y9sCPQoUi57kSO4HI5/YEzuhf9kXCly2wIDAQAB";
        System.out.print(AlipaySignature.rsaCheckV1(map, publickKey, "UTF-8", "RSA2"));
    }

}
